package com.miracle9.game.server.message;

import com.miracle9.game.bean.DeskSeatBean;
import com.miracle9.game.entity.DeviceInfo;
import com.miracle9.game.entity.GameLogs;
import com.miracle9.game.entity.User;
import com.miracle9.game.service.XsManageService;
import com.miracle9.game.service.XxFishService;
import com.miracle9.game.util.GameParameterAssist;
import com.miracle9.game.util.HexUtil;
import com.miracle9.game.util.MyUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;


import java.net.InetSocketAddress;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//@Service("xsSocketHandler")
public class XsSocketHandler implements IoHandler {

    private  XsManageService xsManageService;

    private String device;

    public XsSocketHandler(){

    }

    public XsSocketHandler( XsManageService xsManageService ){
        this.xsManageService = xsManageService;
    }
    private Logger logger = Logger.getLogger(XsSocketHandler.class);
    public void sessionCreated(IoSession ioSession) throws Exception {
        logger.info("xs socket success");
    }

    public void sessionOpened(IoSession session) throws Exception {
        String clientIP = ((InetSocketAddress) session.getRemoteAddress()).getAddress().getHostAddress();
        session.setAttribute("ip", clientIP);
        this.logger.info("硬件交互服务打开  sessionOpened, xs IP:" + clientIP);
    }

    public void sessionClosed(IoSession ioSession) throws Exception {
        this.logger.info("sessionClosed...");
        if(!MainServer.yjsocket.isEmpty()){
            if(MainServer.yjsocket.containsKey(this.device)){
                MainServer.yjsocket.remove(this.device);
            }
        }
    }

    public void sessionIdle(IoSession ioSession, IdleStatus idleStatus) throws Exception {
     //   this.logger.info("sessionIdle...");
    }

    public void exceptionCaught(IoSession ioSession, Throwable throwable) throws Exception {
        logger.info("exceptionCaught....." );
        logger.error("error ",throwable);
        ioSession.close(true);
        if(!MainServer.yjsocket.isEmpty()){
            if(MainServer.yjsocket.containsKey(this.device)){
                MainServer.yjsocket.remove(this.device);
            }
        }
    }

    public void messageReceived(IoSession session, Object o) throws Exception {
        try {
            IoBuffer in = (IoBuffer) o;
            String code  = in.getHexDump();
            logger.info("request info:" + code);
            String[] codes = code.split(" ");
            if(codes[3].equals("80")){ // 设备登录 服务器
                //验证设备码是否存在
                String device = codes[4]+codes[5]+codes[6]+codes[7];
                List<DeviceInfo> list = xsManageService.q_CreateSqlList("from DeviceInfo where device=? and status=1 order by id",new Object[]{device});
                if(CollectionUtils.isNotEmpty(list)){
                    if(MainServer.yjsocket.containsKey(device)){
                        MainServer.yjsocket.get(device).close(true);
                        MainServer.yjsocket.remove(device);
                    }
                    MainServer.yjsocket.put(device,session);
                    this.device = device;
                    logger.info("login success device = " + device);
                    sendMsg(session,"FA 17 00 80 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 96 FB");
                //    sendMsg(session,"FA 0C 00 71 01 01 00 00 01 00 7C FB");
                }else {
                    logger.info("login fail device = " + device);
                    sendMsg(session,"FA 17 00 80 00 00 00 00 00 00 0f 00 00 00 00 00 00 00 00 00 00 A5 FB");
                }
            }else if(codes[3].equals("71")){ //会员投币
                for (Map.Entry<Integer, DeskSeatBean> entry :  XxFishService.userDeskSeatMap.entrySet()) {
                    if (codes[4].equals(entry.getValue().seat)) {
                        Map<String, Object> result = new HashMap<>();
                        result.put("userId", entry.getKey());
                        result.put("seat", entry.getValue().seat);
                        MessageSend.q.notifyAllOperating(new StorageMethodEntity(GameParameterAssist.ba.get(entry.getKey()), "leaveRoom", new Object[]{result}));
                    }
                }
            }else if(codes[3].equals("81")){ //心跳包
                String device = codes[4]+codes[5]+codes[6]+codes[7];
                if(MainServer.yjsocket.containsKey(device)){
                    MainServer.yjsocket.remove(device);
                }
                MainServer.yjsocket.put(device,session);
                session.write(o);
            }else if(codes[3].equals("72")){ //退票
                if(codes[5].equals("02")){
                    logger.info("messageReceived return a ticket " + code);
                }else if(codes[5].equals("03")){
                    //退票完成
                    String[] arr = code.split("FB FA");
                    for (int i = 0; i < arr.length; i++) {
                        String arrcode = null;
                        if(i == 0){
                            arrcode = arr[i] + "FB";
                        }else if(i == arr.length-1){
                            arrcode = "FA"+arr[i];
                        }else {
                            arrcode = "FA"+arr[i]+"FB";
                        }
                        String[] codearr =arrcode.split(" ");
                        String am = codearr[6];
                        String am1 = codearr[7];
                        logger.info("messageReceived return a ticket success " + arr[i] + ",am="+am+",am1 = " + am1);
                        int userId = 0;
                        for (Map.Entry<Integer, DeskSeatBean> entry :  XxFishService.userDeskSeatMap.entrySet()) {
                            if (codearr[4].equals("0"+entry.getValue().getSeat())) {

                                User user = xsManageService.getUserById(entry.getKey());
                                userId = user.getId();
                                int amount =  Integer.parseInt(am,16) +  Integer.parseInt(am1,16) ;
                                GameLogs gameLogs = new GameLogs();
                                gameLogs.setRoomId(entry.getValue().getDeskId());
                                gameLogs.setUserId(entry.getKey());
                                gameLogs.setPromoterId(user.getPromoterId());
                                gameLogs.setUserName(user.getNickname());
                                gameLogs.setValue(amount);
                                gameLogs.setBeforeamount(user.getGameGold());
                                gameLogs.setActual(user.getGameGold()+amount);
                                gameLogs.setStatus(2);//1  投币 2 退票
                                gameLogs.setSeatId(entry.getValue().getSeat());
                                gameLogs.setDatetime(MyUtil.dateFormatYMD_HMS_Sting(new Date()));
                                xsManageService.gameLogsSave(gameLogs);
                                xsManageService.updateGameById(user.getId(),amount,0);

                                Map<String, Object> result = new HashMap<>();
                                result.put("userId", entry.getKey());
                                result.put("seat", entry.getValue().seat);
                                result.put("deskId", entry.getValue().getDeskId());
                                result.put("amount", amount);
                                result.put("integral", amount*100);


                                Map<String, Object> result1 = new HashMap<>();
                                result1.put("gameGold", user.getGameGold()+amount);
                                logger.info("push user amount userId= "+entry.getKey());
                                MessageSend.q.notifyAllOperating(new StorageMethodEntity(GameParameterAssist.ba.get(entry.getKey()), "newGameGold", new Object[]{result1}));
                                if(MainServer.timeout.containsKey(entry.getValue().getSeat())){
                                    logger.info("user timeout seat " + entry.getValue().getSeat());
                                    XxFishService.userDeskSeatMap.remove(entry.getKey());
                                    MainServer.timeout.remove(entry.getValue().getSeat());

                                    MessageSend.q.notifyAllOperating(new StorageMethodEntity(GameParameterAssist.ba.get(entry.getKey()), "ticketConfirmTimeOut", new Object[]{result}));
                                    for (IoSession as : GameParameterAssist.ba.values()) {
                                        Map<String, Object> result2 = new HashMap<>();
                                        result2.put("userId", user.getId());
                                        result2.put("seatId", entry.getValue().getSeat());
                                        result2.put("deskId", entry.getValue().getDeskId());
                                        result2.put("gameType", entry.getValue().getGameType());
                                        MessageSend.q.notifyAllOperating(new StorageMethodEntity(as, "notifyDesk", new Object[]{result2}));
                                    }

                                }else {
                                    logger.info("push user ticketConfirm userId= "+entry.getKey());
                                    MessageSend.q.notifyAllOperating(new StorageMethodEntity(GameParameterAssist.ba.get(entry.getKey()), "ticketConfirm", new Object[]{result}));
                                }
                            }
                        }
                        //  session.write(o);
                        sendMsg(session,arrcode);
                    }

                }
            }
        } catch (Exception e) {
            this.logger.error("error ", e);
        }
    }

    public void messageSent(IoSession ioSession, Object o) throws Exception {
       // logger.info("messageSent....." + o );
    }
    public static void sendMsg(IoSession session,String msg){
        try {
            byte[] data = HexUtil.hexStringToByteArray(msg);
            IoBuffer bb = IoBuffer.allocate(data.length);
            bb.put(data, 0, data.length);
            bb.flip();
            session.write(bb);
        } catch (Exception e) {
           e.printStackTrace();
        }
    }
}
